package link.jfire.simplerpc.server.messagehandler;

import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import link.jfire.baseutil.collection.StringCache;
import link.jfire.baseutil.simplelog.ConsoleLogFactory;
import link.jfire.baseutil.simplelog.Logger;
import link.jfire.codejson.JsonArray;
import link.jfire.codejson.JsonObject;
import link.jfire.socket.socketserver.bus.Message;
import link.jfire.socket.socketserver.handler.MessageHandler;

@Resource
public class InfoMessageHandler implements MessageHandler
{
    private byte[] info;
    private Logger logger = ConsoleLogFactory.getLogger();
    
    @Override
    public byte interestedDataPacketType()
    {
        return InvokeType.METHOD_INFO;
    }
    
    @Override
    public void handler(Message message)
    {
        message.getBusinessData().putArray(info);
    }
    
    /**
     * 设置必须的工作单元，包含代理名称数组，代理实例
     * 
     * @param proxyNames
     * @param impls
     * @param methodMaps
     */
    public void setWorkUnit(String[] proxyNames, Object[] impls)
    {
        JsonObject jsonObject = new JsonObject();
        JsonArray jsonArray = new JsonArray();
        for (int i = 0; i < proxyNames.length; i++)
        {
            jsonArray.add(new ProxyBean(impls[i].getClass(), proxyNames[i]));
        }
        jsonObject.put("methodInfo", jsonArray);
        logger.info(jsonObject.toString());
        info = jsonObject.toString().getBytes(Charset.forName("utf8"));
    }
}

@SuppressWarnings("unused")
class ProxyBean
{
    private String           proxyName;
    private List<MethodBean> methods;
    
    public ProxyBean(Class<?> bean, String proxyName)
    {
        this.proxyName = proxyName;
        ArrayList<MethodBean> list = new ArrayList<>();
        while (bean != Object.class)
        {
            for (Method method : bean.getDeclaredMethods())
            {
                list.add(new MethodBean(method));
            }
            bean = bean.getSuperclass();
        }
        methods = list;
    }
}

@SuppressWarnings("unused")
class MethodBean
{
    
    private String methodName;
    private int    paramNum;
    private String params;
    private String returnType;
    
    public MethodBean(Method method)
    {
        methodName = method.getName();
        Class<?>[] paramTypes = method.getParameterTypes();
        paramNum = paramTypes.length;
        returnType = method.getReturnType().getName();
        if (paramNum == 0)
        {
            return;
        }
        StringCache cache = new StringCache();
        for (Class<?> each : paramTypes)
        {
            cache.append(each.getSimpleName()).appendComma();
        }
        if (cache.isCommaLast())
        {
            cache.deleteLast();
        }
        params = cache.toString();
    }
    
}
